import { math, Vec2, Vec4 } from 'cc';
import { BaseView, UIOrder } from '../../mvc/base_view';
import { CollectPool } from '../../shared/collect_pool';
import { UtilsInstance } from '../../shared/utils';
import { Player } from '../data/player';
import { GameController } from '../game_controller';
import { HandCard } from './hand_card';
import { PlayerItem } from './player_item';

/**
 * 游戏桌面
 */

enum GameState{
    Waiting = 0,
    Begining = 1,
    Playing = 2,
    End = 3,
}

export enum GameSubState{
    InitHandCard1 = 1,
    InitHandCard2 = 2,
    InitHandCard3 = 3,
    InitHandCard4 = 4,
    InitHandCard5 = 5,
    //----
    CheckTurnPlayer = 1,
    CheckPlayerType = 2,
    UpdatePlayerTime = 3,
    UpdateHangPlayerTime = 4,
    PlayPlayerPickCard = 5,
    PlayPlayerSendCard1 = 6,
    PlayPlayerSendCard2 = 7,
    PlayStealCard = 8,
    PlayPlayerChangeCard = 9,
    PlayChooseCard = 10,
    PlayPutBoom = 11,
    NextTurn = 12,
}

enum CardType{
    Boom = 1,
    DefuseBoom = 2,
    AnyCard = 3,
    TurnArround = 4,
    JumpTurn = 5,
    ShuffleCard = 6,
    PickBottomCard = 7,
    SeeTopCard = 8,
    SearchBoom = 9,
    ChangeHandCard = 10,
    StealCard = 11,
    AddPickCardNum = 12,
}

export class MainView extends BaseView {
    total_card_num:number;
    card_heap_conf:any;
    card_heap_list:Array<number>;
    player_list:Array<PlayerItem>;
    MeCanAction:boolean;
    hand_card_pool:CollectPool;
    hand_card_list:Array<HandCard>;
    send_card_list:Array<HandCard>;
    hand_card_rect:Vec4;
    card_heap_rect:Vec2;
    send_card_rect:Vec2;
    game_state:number;
    game_sub_state:number;
    game_action_state:number;
    game_state_time:number;
    game_player_index:number;
    turn_player_item:PlayerItem;
    turn_time:number;
    turn_face:number;
    pick_card:HandCard;
    select_card:HandCard;
    send_card:HandCard;
    show_card_time:number;
    temp_move_rect:Vec2;
    temp_move_rect1:Vec2;
    target_player_item:PlayerItem;
    change_card_list1:Array<HandCard>;
    change_card_list2:Array<HandCard>;
    constructor(){
        super();
        this.ui_package = "main";
        this.layout_name = "ui_main_view";
        this.order = UIOrder.Main;
        this.game_state_time = 0;
    }

    OpenViewCallback(...args: any[]){
        //游戏开始前的初始化
        this.game_state = GameState.Waiting;
        this.SetSelectedIndex("game_state", 0);
        this.GetGButton("start_btn").onClick(()=>{
            this.player_list = new Array<PlayerItem>();
            let my_player:Player = new Player(1, "风雨不改", true, true);
            let player_item1 = new PlayerItem(this.GetCom("player1"));
            player_item1.SetPlayer(my_player);
            this.player_list.push(player_item1);
            let enemy_player:Player = new Player(2, "大兵哥", false, false);
            enemy_player.SetHang(true);
            let player_item2 = new PlayerItem(this.GetCom("player2"));
            player_item2.SetPlayer(enemy_player);
            this.player_list.push(player_item2);
            this.StartGame();
        });

        this.hand_card_pool = new CollectPool(() =>{
            return new HandCard(this.fairy_root);
        }, (item)=>{
            item.Close();
        }, (item)=>{
            item.Reset();
        });

        this.hand_card_list = new Array<HandCard>();
        this.send_card_list = new Array<HandCard>();

        // 初始化一些点位
        let card_heap = this.GetGGraph("card_heap");
        this.card_heap_rect = new Vec2(card_heap.x, card_heap.y);

        let handcard_rect = this.GetGGraph("handcard_rect");
        this.hand_card_rect = new Vec4(handcard_rect.x, handcard_rect.y, handcard_rect.width, handcard_rect.height);

        let send_card_rect = this.GetGGraph("send_card_rect");
        this.send_card_rect = new Vec2(send_card_rect.x, send_card_rect.y);
    }

    ResetGameData(){
        this.hand_card_list.forEach(hand_card => {
            this.hand_card_pool.Free(hand_card);
        });
        this.hand_card_list.splice(0, this.hand_card_list.length);

        this.send_card_list.forEach(hand_card => {
            this.hand_card_pool.Free(hand_card);
        });
        this.send_card_list.splice(0, this.send_card_list.length);

        this.player_list.forEach(player_item => {
            player_item.DeleteMe();
        });
        this.player_list.splice(0, this.player_list.length);
    }

    StartGame(){
        this.game_state = GameState.Begining;
        this.game_player_index = 0;

        this.SetSelectedIndex("game_state", 1);

        // 初始化牌堆
        let player_length = this.player_list.length;
        this.card_heap_conf = config.play_mode[player_length.toString()];
        this.card_heap_list = new Array<number>();
        this.card_heap_conf.card_heap_pack.forEach((num, card_type) => {
            for (let index = 0; index < num; index++) {
                this.card_heap_list.push(card_type + 1);     
            }  
        });
        this.ShuffleCardHeap();
        this.card_heap_list.push(CardType.Boom);
        this.total_card_num = player_length * this.card_heap_conf.init_handcard_num + this.card_heap_list.length;

        // 开局发牌
        let one_player_card_num = this.card_heap_conf.init_handcard_num;
        
        this.player_list.forEach(player_item => {
            let player = player_item.player;
            this.total_card_num = this.total_card_num - 1;
            for (let index = 0; index < one_player_card_num - 1; index++) {
                this.InitCardType(player);
            }
            player.PushCardType(CardType.AnyCard);
        });
       

        this.GetGButton("pick_card_btn").onClick(()=>{
            if(!this.MeCanAction){
                this.PushTips(config.words["104"])
                return;
            }

            if(this.pick_card != null){
                return;
            }

            this.PickCard(false);
        })

        this.GetGButton("send_card_btn").onClick(()=>{
            if(!this.MeCanAction){
                this.PushTips(config.words["104"])
                return;
            }

            if(this.pick_card != null){
                return;
            }

            if(this.send_card != null){
                return;
            }

            if(this.select_card != null){
                let card_conf = config.card[this.select_card.card_type.toString()];
                if(card_conf.is_target && this.target_player_item == null){
                    this.PushTips(config.words["107"])
                    return;
                }
                this.SendCard(0);
            }else{
                this.PushTips(config.words["105"])
            }
            
        })

        this.game_sub_state = GameSubState.InitHandCard1;
        this.turn_face = 0;
    }

    Update(elapse_time:number){
        this.game_state_time = this.game_state_time + elapse_time;

        if(this.game_state == GameState.Begining){
            if(this.game_sub_state == GameSubState.InitHandCard1){
                // 初始化自己的手牌
                this.player_list.forEach(player_item => {
                    if(player_item.player.is_me){
                        player_item.player.card_type_list.forEach((card_type) => {
                            let card = this.CreateHandCard(card_type, this.hand_card_rect)
                            this.hand_card_list.push(card);
                        });
                        this.game_sub_state = GameSubState.InitHandCard2;
                        return;
                    }
                });
            }
            
            else if(this.game_sub_state == GameSubState.InitHandCard2){
                let is_all_open = true;
                this.hand_card_list.forEach(card => {
                    if(!card.IsOpen()){
                        is_all_open = false;
                    }
                });
                if(is_all_open){
                    this.game_sub_state = GameSubState.InitHandCard3;
                }
            }
            
            else if(this.game_sub_state == GameSubState.InitHandCard3){
                this.UpdateHandCardArea();
                this.game_sub_state = GameSubState.InitHandCard4;
                this.game_state_time = 0;
            }
            
            else if(this.game_sub_state == GameSubState.InitHandCard4){
                if(this.game_state_time >= 1){
                    this.hand_card_list.forEach(card => {
                        card.TurnCard();
                    });
                    this.game_sub_state = GameSubState.InitHandCard5;
                }
            }
            
            else if(this.game_sub_state == GameSubState.InitHandCard5){
                this.player_list.forEach(player_item => {
                    player_item.UpdateInfo();
                });
                this.game_state = GameState.Playing;
                this.game_sub_state = GameSubState.CheckTurnPlayer;
            }

        }else if(this.game_state == GameState.Playing){
            let player:Player;
            if(this.turn_player_item != null){
                player = this.turn_player_item.player;
            }

            if(this.game_sub_state == GameSubState.CheckTurnPlayer){
                let player_item = this.player_list[this.game_player_index];
                let player = player_item.player;
                if(player.is_alive){
                    this.turn_player_item = player_item;
                    this.turn_time = config.game_general.turn_time;
                    this.game_sub_state = GameSubState.CheckPlayerType;
                }else{
                    this.turn_player_item = null;
                    this.game_sub_state = GameSubState.NextTurn;
                }
            }

            else if(this.game_sub_state == GameSubState.CheckPlayerType){
                if(player.is_me){
                    this.MeCanAction = true;
                    this.game_sub_state = GameSubState.UpdatePlayerTime;
                }else{
                    if(player.is_hang){
                        player.PrepareHang();
                        this.game_sub_state = GameSubState.UpdateHangPlayerTime;
                    }else{
                        this.game_sub_state = GameSubState.UpdatePlayerTime;
                    }
                }
            }
            
            else if(this.game_sub_state == GameSubState.UpdatePlayerTime){
                 // 等待操作
                this.TurnTimeTick(elapse_time);

                if(!player.is_alive){
                    this.game_sub_state = GameSubState.NextTurn;
                }
            } 
            
            else if(this.game_sub_state == GameSubState.PlayPlayerPickCard){
                if(this.pick_card.IsOpen()){// 摸牌表现
                    if(player.is_me){
                        if (this.show_card_time == 0){
                            this.pick_card.TurnCard();
                        }
                    }
                    this.show_card_time = this.show_card_time + elapse_time;
                    if(player.is_me){
                        if(this.show_card_time >= 0.5){
                            let new_pos = UtilsInstance.vectorLerp(this.card_heap_rect, this.temp_move_rect, this.show_card_time - 0.5)
                            this.pick_card.SetPosition(new_pos.x, new_pos.y)
                            if(this.show_card_time >= 1.5){
                                let pick_card_type = this.pick_card.card_type;
                                if(pick_card_type == CardType.Boom){  
                                    this.hand_card_pool.Free(this.pick_card);      
                                    player.PickBoom();
                                    let have_use = this.HaveUseDefuseBoomCard(player);
                                    if(!have_use){
                                        player.is_alive = false;
                                        this.game_sub_state = GameSubState.NextTurn;
                                    }
                                }else{                                 
                                    this.UpdateHandCardArea();
                                    this.game_sub_state = GameSubState.NextTurn;
                                }
                                this.pick_card = null;     
                            }
                        }
                    }else{
                        let new_pos = UtilsInstance.vectorLerp(this.card_heap_rect, this.temp_move_rect, this.show_card_time);
                        this.pick_card.SetPosition(new_pos.x, new_pos.y);
                        let new_scale = UtilsInstance.vectorLerp(new Vec2(1, 1), new Vec2(0.2, 0.2), this.show_card_time);
                        this.pick_card.SetScale(new_scale.x, new_scale.y);
                        if(this.show_card_time >= 1){
                            let pick_card_type = this.pick_card.card_type;
                            if(player.is_hang){
                                if(pick_card_type == CardType.Boom){
                                    player.PickBoom();
                                    let have_use = this.HaveUseDefuseBoomCard(player);
                                    if(!have_use){
                                        player.is_alive = false;
                                        this.game_sub_state = GameSubState.NextTurn;
                                    }
                                }else{
                                    this.game_sub_state = GameSubState.NextTurn;
                                }
                            }else{
                                if(pick_card_type == CardType.Boom){
                                    player.PickBoom();
                                }
                                this.game_sub_state = GameSubState.UpdatePlayerTime;
                            }
                            this.hand_card_pool.Free(this.pick_card);
                            this.pick_card = null;
                        }
                    }
                }              
            } 
            
            else if(this.game_sub_state == GameSubState.PlayPlayerSendCard1){
                //出牌表现
                if(this.send_card.IsOpen()){
                    if(this.send_card.face == 0){
                        this.send_card.TurnCard();
                    }
                    this.show_card_time = this.show_card_time + elapse_time;
                    let new_pos = UtilsInstance.vectorLerp(this.temp_move_rect, this.send_card_rect, this.show_card_time);
                    this.send_card.SetPosition(new_pos.x, new_pos.y)
                    if(this.show_card_time >= 1){
                        this.send_card_list.push(this.send_card);

                        if(player.is_me){
                            this.RemoveHandCardListElement(this.send_card);
                            this.UpdateHandCardArea();     
                        }       
                        this.game_sub_state = GameSubState.PlayPlayerSendCard2;
                        this.DoCardEffect();  
                    }
                }
            } 
            
            else if(this.game_sub_state == GameSubState.PlayPlayerSendCard2){    
                //出牌表现2
            }
            
            else if(this.game_sub_state == GameSubState.PlayStealCard){    
                //偷牌表现
                if(this.pick_card.IsOpen()){
                    this.show_card_time = this.show_card_time + elapse_time;
                    let new_pos = UtilsInstance.vectorLerp(this.temp_move_rect, this.temp_move_rect1, this.show_card_time);
                    this.pick_card.SetPosition(new_pos.x, new_pos.y);
                    if(!player.is_me){
                        let new_scale = UtilsInstance.vectorLerp(new Vec2(1, 1), new Vec2(0.2, 0.2), this.show_card_time);
                        this.pick_card.SetScale(new_scale.x, new_scale.y);
                    }
                    if(this.show_card_time >= 1){
                        if(player.is_me){
                            this.pick_card.TurnCard();
                            this.UpdateHandCardArea();
                            this.game_sub_state = GameSubState.NextTurn;
                        }else{
                            this.hand_card_pool.Free(this.pick_card);
                            this.pick_card = null;
                            if(player.is_hang){
                                this.ChangeGameSubState(GameSubState.NextTurn);
                            }else{
                                this.game_sub_state = GameSubState.UpdatePlayerTime;
                            }
                        }
                    }
                }   
            } 
            
            else if(this.game_sub_state == GameSubState.PlayPlayerChangeCard){
                //调换牌表现
                let all_open = true;
                this.change_card_list1.forEach(hand_card => {
                    if(!hand_card.IsOpen){
                        all_open = false;
                    }
                });

                this.change_card_list2.forEach(hand_card => {
                    if(!hand_card.IsOpen){
                        all_open = false;
                    }
                });

                if(all_open){
                    this.show_card_time = this.show_card_time + elapse_time;
                    let change_card_total_time1 = (this.change_card_list1.length - 1) * 0.2 + 1;
                    if(this.show_card_time <= change_card_total_time1){
                        this.change_card_list1.forEach((hand_card, card_index) => {
                            let show_card_time = this.show_card_time - (card_index * 0.2);
                            let new_pos = UtilsInstance.vectorLerp(this.temp_move_rect, this.temp_move_rect1, show_card_time);
                            hand_card.SetPosition(new_pos.x, new_pos.y);
                            let new_scale = UtilsInstance.vectorLerp(new Vec2(1, 1), new Vec2(0.2, 0.2), show_card_time);
                            hand_card.SetScale(new_scale.x, new_scale.y);
                        });
                    }else{
                        let change_card_total_time2 = (this.change_card_list2.length - 1) * 0.2 + 1 + change_card_total_time1;
                        if(this.show_card_time <= change_card_total_time2){
                            this.change_card_list2.forEach((hand_card, card_index) => {
                                let show_card_time = this.show_card_time - (card_index * 0.2) - change_card_total_time1;
                                let new_pos = UtilsInstance.vectorLerp(this.temp_move_rect1, this.temp_move_rect, show_card_time);
                                hand_card.SetPosition(new_pos.x, new_pos.y);                      
                                if(!player.is_me){
                                    let new_scale = UtilsInstance.vectorLerp(new Vec2(1, 1), new Vec2(0.2, 0.2), show_card_time);
                                    hand_card.SetScale(new_scale.x, new_scale.y);
                                }
                            });
                        }else{
                            if(player.is_me){
                                this.hand_card_list = this.change_card_list2.slice();
                                this.change_card_list2 = null;
                                this.hand_card_list.forEach(hand_card => {
                                    hand_card.TurnCard();
                                });
                                this.UpdateHandCardArea();
                            }else{
                                this.change_card_list2.forEach(hand_card => {
                                    this.hand_card_pool.Free(hand_card);
                                });
                                this.change_card_list2 = null;
                            }
                            this.change_card_list1.forEach(hand_card => {
                               this.hand_card_pool.Free(hand_card);
                            });
                            this.change_card_list1 = null;
                           
                            if(player.is_hang){
                                this.ChangeGameSubState(GameSubState.NextTurn);
                            }else{
                                this.game_sub_state = GameSubState.UpdatePlayerTime;
                            }
                        }
                    }
                }
            } 
            
            else if(this.game_sub_state == GameSubState.PlayChooseCard){
                //等待选择变卡完毕
            }

            else if(this.game_sub_state == GameSubState.PlayPutBoom){
                //等待放炸弹完毕
            }

            else if(this.game_sub_state == GameSubState.UpdateHangPlayerTime){
                //托管玩家
                this.TurnTimeTick(elapse_time);

                if(!player.is_alive){
                    this.game_sub_state = GameSubState.NextTurn;
                    return;
                }

                player.hang_state_time = player.hang_state_time - elapse_time;
                if(player.hang_state_time <= 0){
                    if(player.hang_state_action == 1){
                        // 抽卡
                        this.PickCard(false);
                    }else if(player.hang_state_action == 2){
                        // 出牌
                        let card_index = math.randomRangeInt(0, player.card_type_list.length);
                        let card_type = player.card_type_list[card_index];
                        let card_conf = config.card[card_type.toString()];
                        if(card_conf.is_target){
                            this.target_player_item = this.RandomPlayer(card_type, player);
                            if(this.target_player_item == null){
                                player.hang_state_action = 2;
                                return;
                            }
                        }
                        player.card_type_list.splice(card_index, 1);
                        this.SendCard(card_type);
                        player.hang_state_action = 3;
                    }else if(player.hang_state_action == 3){
                       //啥都不干
                    }
                }
            }   
                 
            else if(this.game_sub_state == GameSubState.NextTurn){
                let alive_num = this.player_list.length;
                let win_player_item;
                this.player_list.forEach(player_item => {
                    if(!player_item.player.is_alive){
                        alive_num = alive_num - 1;
                    }else{
                        win_player_item = player_item;
                    }
                });
                if(alive_num == 1){
                    this.game_state = GameState.End;
                    this.PushTips(UtilsInstance.formatString(config.words["111"],  win_player_item.player.user_name));
                    GameController.getInstance().OpenEndView(()=>{
                        this.ResetGameData();

                        this.game_state = GameState.Waiting;
                        this.SetSelectedIndex("game_state", 0);
                    })
                    return;
                }

                if(this.turn_player_item != null){
                    let player = this.turn_player_item.player;
                    if(player.extra_turn_num > 0){
                        player.SubExtraTurnNum(1);
                        this.turn_time = config.game_general.turn_time;
                        this.game_sub_state = GameSubState.CheckPlayerType;
                        return;
                    }
                }

                if(this.turn_face == 0){ // 正序
                    this.game_player_index = this.game_player_index + 1;
                    if(this.game_player_index == this.player_list.length){
                        this.game_player_index = 0;
                    }
                }else{
                    this.game_player_index = this.game_player_index - 1;
                    if(this.game_player_index == -1){
                        this.game_player_index = this.player_list.length - 1;
                    }
                }
               
                this.game_sub_state = GameSubState.CheckTurnPlayer;
            }
        }
        
        else if(this.game_state == GameState.End){

        }

    }

    TurnTimeTick(elapse_time:number){
        this.turn_time = this.turn_time - elapse_time;               
        if(this.turn_time <= 0){
            if(this.turn_player_item.player.is_me){
                this.PickCard(false);
                return;
            }
            this.game_sub_state = GameSubState.NextTurn;
        }
        this.GetGText("common_tips").text = UtilsInstance.formatString(config.words["103"], this.turn_player_item.player.user_name, Math.floor(this.turn_time));
    }


    PickCard(from_bottom:boolean){
        this.total_card_num = this.total_card_num - 1;
        this.GetGText("total_card_num").text = UtilsInstance.formatString(config.words["100"], this.total_card_num);

        let card_type 
        if(from_bottom){
            card_type = this.card_heap_list[0];
            this.card_heap_list.splice(0, 1);
        }else{
            card_type = this.card_heap_list.pop();
        }
       
        let player:Player = this.turn_player_item.player;
        if(card_type != CardType.Boom){
            player.PushCardType(card_type);
        }

        let card = this.CreateHandCard(card_type, this.card_heap_rect);
        this.pick_card = card;
        this.show_card_time = 0;

        if(player.is_me){
            if(this.select_card != null){
                this.select_card.Selected(false);
                this.select_card = null;
            }
            if(card_type != CardType.Boom){
                this.hand_card_list.push(card);
            }
            this.temp_move_rect = new Vec2(this.hand_card_rect.x + this.hand_card_rect.z / 2, this.hand_card_rect.y);
            this.MeCanAction = false;
        }else{
            this.temp_move_rect = this.turn_player_item.GetPosition();
        }
        this.game_sub_state = GameSubState.PlayPlayerPickCard;
        this.turn_player_item.UpdateInfo();
    }

    InitCardType(player:Player):number{
        this.total_card_num = this.total_card_num - 1;
        this.GetGText("total_card_num").text = UtilsInstance.formatString(config.words["100"], this.total_card_num);

        let attack_card_num = 0;
        player.card_type_list.forEach(card_type => {
            if(card_type == CardType.AddPickCardNum){
                attack_card_num = Math.min(attack_card_num + 1, this.card_heap_conf.attack_card_random_weight.length); 
            }
        });
        let attack_card_rate = this.card_heap_conf.attack_card_random_weight[attack_card_num] * 100;
        let type = 0;
        if(math.randomRangeInt(1, 101) < attack_card_rate){
            type = CardType.AddPickCardNum
        }else{
            type = math.randomRangeInt(2, config.game_general["total_random_card_type"]); // 炸弹牌不会出现在初始手牌
        }      
        player.PushCardType(type);
        return type;
    }

    SendCard(card_type:number){
        let player:Player = this.turn_player_item.player;
        if(player.is_me){
            this.CloseSelectTarget();
            if(this.select_card == null){
                this.hand_card_list.forEach(hand_card => {
                    if(hand_card.card_type == card_type){
                        this.send_card = hand_card;
                        return;
                    }
                });
            }else{
                this.send_card = this.select_card;
            }
            
            this.temp_move_rect = this.send_card.GetPosition();
            this.select_card = null;
        }else{
            this.send_card = this.CreateHandCard(card_type, this.turn_player_item.GetPosition());
            this.temp_move_rect = this.turn_player_item.GetPosition();
        }
        this.send_card.SetScale(1,1);
        this.game_sub_state = GameSubState.PlayPlayerSendCard1;
        this.show_card_time = 0;

        if(this.send_card.card_type == CardType.AnyCard){
            // 神卡直接触发效果
            this.DoCardEffect();
        }
    }

    CreateHandCard(card_type:number, born_rect):HandCard{
        let card = this.hand_card_pool.Create();
        card.Open(()=>{
            card.SetInfo(card_type, born_rect, ()=>{
                if(this.game_sub_state != GameSubState.UpdatePlayerTime){
                    return;
                }

                if(this.select_card != null){
                    this.select_card.Selected(false);
                }
                card.Selected(true);
                this.select_card = card;

                this.CloseSelectTarget();
                let card_conf = config.card[card_type.toString()];
                
                if(card_conf.is_target){
                    this.GetGGraph("target_tips").visible = true;
                    this.player_list.forEach(player_item => {
                        let player = player_item.player;
                        let card_type_for_select = this.CardTypeCanSelect(card_type, player);
                
                        if(!player.is_me && player.is_alive && card_type_for_select){
                            player_item.SetClickCallback(()=>{
                                if(this.target_player_item != null){
                                    this.target_player_item.Selected(false);
                                }
                                player_item.Selected(true);
                                this.target_player_item = player_item;
                            });
                        }else{
                            player_item.SetSelectedIndex("select_state", 1);
                        }
                    });
                }
            });
        });
        return card;
    }

    CardTypeCanSelect(card_type:number, player:Player):boolean{
        let card_type_for_select = true;
        if(card_type == CardType.StealCard){
            if(player.card_type_list.length == 0){
                card_type_for_select = false;
            }
        }
        return card_type_for_select;
    }

    CloseSelectTarget(){
        this.player_list.forEach(player_item => {
            this.GetGGraph("target_tips").visible = false;
            player_item.Selected(false);
            player_item.SetSelectedIndex("select_state", 0);
        });
    }

    UpdateHandCardArea(){
        let index:number = 0;
        let offset = this.hand_card_rect.z / this.hand_card_list.length;
        this.hand_card_list.forEach(card => {
            card.SetPosition(this.hand_card_rect.x + card.width / 2  + index * offset, this.hand_card_rect.y);
            index = index + 1;
        });
    }

    PushTips(words:string){
        this.GetGText("push_tips").text = words;
        this.PlayTransition("push_tips");
    }

    ChangeGameSubState(game_sub_state:number){
        this.game_sub_state = game_sub_state;
    }

    RemoveHandCardListElement(remove_card:HandCard){
        this.hand_card_list.forEach((card, index) => {
            if(card == remove_card){
                this.hand_card_list.splice(index, 1);
                this.turn_player_item.player.RemoveCardIndex(index);
                return;
            }
        });
    }

    RandomPlayer(card_type:number, mePlayer:Player):PlayerItem{
        let can_random_player_list = new Array<number>();
        this.player_list.forEach((player_item, player_index) => {
            let player = player_item.player;
            if(player != mePlayer){
                let card_type_for_select = this.CardTypeCanSelect(card_type, player);     
                if(!player.is_me && player.is_alive && card_type_for_select){
                    can_random_player_list.push(player_index);
                }
            }   
        });
        let index = math.randomRangeInt(0, can_random_player_list.length);
        return this.player_list[can_random_player_list[index]];
    }

    ShuffleCardHeap(){
        let numberOfCards = this.card_heap_list.length;
        for (let i = numberOfCards - 1; i > 0; i--) {
            const randomIndex: number = Math.floor(Math.random() * (i + 1));
    
            // 交换位置
            const temp: number = this.card_heap_list[i];
            this.card_heap_list[i] = this.card_heap_list[randomIndex];
            this.card_heap_list[randomIndex] = temp;
        }
    }

    ChangeToGamePlayUpdateTime(player:Player, is_send:boolean){
        if(player.is_me){
            this.game_sub_state = GameSubState.UpdatePlayerTime;
        }else{
            this.game_sub_state = GameSubState.UpdateHangPlayerTime;
            if(is_send){
                this.PickCard(false);
            }
        }
    }

    HaveUseDefuseBoomCard(player:Player):boolean{
        let have_use = false;
        player.card_type_list.forEach(card_type => {
            if(card_type == CardType.DefuseBoom){ // 自动使用拆弹牌
                this.SendCard(card_type);
                have_use = true;
                return;
            }
        });
        return have_use;
    }

    DoCardEffect(){ //解析并表现卡牌效果
        let player = this.turn_player_item.player;
        let card_type = this.send_card.card_type;
        let card_conf = config.card[card_type.toString()];
        if(card_conf.is_target){
            let target_player = this.target_player_item.player;
            this.PushTips(UtilsInstance.formatString(config.words["108"], player.user_name, target_player.user_name, card_conf.name));
            if(card_type == CardType.AddPickCardNum){
                target_player.AddExtraTurnNum(1);
                this.ChangeToGamePlayUpdateTime(player, true);
            }else if(card_type == CardType.StealCard){
                let steal_card_index = math.randomRangeInt(0, target_player.card_type_list.length);
                let steal_card_type = target_player.card_type_list[steal_card_index];
                target_player.card_type_list.splice(steal_card_index, 1);
                player.card_type_list.push(steal_card_type);
                let steal_card = this.CreateHandCard(steal_card_type, this.target_player_item.GetPosition());
                this.pick_card = steal_card;
                this.show_card_time = 0;
                this.temp_move_rect = this.target_player_item.GetPosition();
                if(player.is_me){
                    this.temp_move_rect1 = new Vec2(this.hand_card_rect.x + this.hand_card_rect.z / 2, this.hand_card_rect.y);
                    this.hand_card_list.push(steal_card);
                }else{
                    this.temp_move_rect1 = this.turn_player_item.GetPosition();
                }
                
                this.game_sub_state = GameSubState.PlayStealCard;
            }else if(card_type == CardType.ChangeHandCard){
                let change_card_player_item = this.turn_player_item;
                if(player.is_me || target_player.is_me){
                    this.change_card_list1 = this.hand_card_list;
                    this.temp_move_rect = new Vec2(this.hand_card_rect.x + this.hand_card_rect.z / 2, this.hand_card_rect.y);
                    if(player.is_me){
                        change_card_player_item = this.target_player_item;
                    }
                }else{
                    this.change_card_list1 = new Array<HandCard>();
                    player.card_type_list.forEach(card_type => {
                        let card = this.CreateHandCard(card_type, this.turn_player_item.GetPosition());
                        this.change_card_list1.push(card);
                        this.temp_move_rect1 = this.turn_player_item.GetPosition();
                    });
                }

                this.change_card_list2 = new Array<HandCard>();
                change_card_player_item.player.card_type_list.forEach(card_type => {
                    let card = this.CreateHandCard(card_type, change_card_player_item.GetPosition());
                    this.change_card_list2.push(card);
                    this.temp_move_rect1 = change_card_player_item.GetPosition();
                });

                let temp_card_type_list:Array<number> = player.card_type_list.slice();
                player.card_type_list = target_player.card_type_list.slice();
                target_player.card_type_list = temp_card_type_list.slice();
                temp_card_type_list = null;

                this.show_card_time = 0;
                this.game_sub_state = GameSubState.PlayPlayerChangeCard;
            }
        }else{
            this.PushTips(UtilsInstance.formatString(config.words["106"], player.user_name, card_conf.name));
            if(card_type == CardType.TurnArround){
                this.turn_face = this.turn_face == 0 ? 1 : 0;
                this.game_sub_state = GameSubState.NextTurn;
            }else if(card_type == CardType.JumpTurn){
                this.game_sub_state = GameSubState.NextTurn;
            }else if(card_type == CardType.ShuffleCard){
                this.ShuffleCardHeap();
                this.ChangeToGamePlayUpdateTime(player, true);
            }else if(card_type == CardType.SearchBoom){
                let boom_card_index;
                this.card_heap_list.forEach((heap_card_type, heap_card_index) => {
                    if(heap_card_type == CardType.Boom){
                        boom_card_index = heap_card_index;
                    }
                });
                if(boom_card_index != null){
                    this.PushTips(UtilsInstance.formatString(config.words["109"], this.card_heap_list.length - boom_card_index));
                }
                this.ChangeToGamePlayUpdateTime(player, true);
            }else if(card_type == CardType.PickBottomCard){
                this.PickCard(true);
            }else if(card_type == CardType.SeeTopCard){
                let see_card_type_list = new Array<number>();
                for (let index = this.card_heap_list.length - 1; index >= 0; index--) {
                    see_card_type_list.push(this.card_heap_list[index]);
                    if(see_card_type_list.length == 3){
                        break;
                    }
                }
                let str = "";
                see_card_type_list.forEach(see_card_type => {
                    str = str + config.card[see_card_type.toString()].name + "   ";
                });
                this.PushTips(UtilsInstance.formatString(config.words["110"], str));
                this.ChangeToGamePlayUpdateTime(player, true);
            }else if(card_type == CardType.AnyCard){
                if(player.is_me){
                    let change_card = this.send_card;
                    GameController.getInstance().OpenChooseCardView((choose_card_type) => {
                        if(choose_card_type != null){
                            player.PushCardType(choose_card_type);
                            change_card.UpdateCardType(choose_card_type);
                        }else{
                            player.PushCardType(CardType.AnyCard);
                        }
                        this.ChangeToGamePlayUpdateTime(player, true);
                    });
                    this.game_sub_state = GameSubState.PlayChooseCard;
                }else{
                    if(player.is_hang){
                        let choose_card_type = math.randomRangeInt(4, 13);
                        player.PushCardType(choose_card_type);
                        this.ChangeToGamePlayUpdateTime(player, true);
                    }
                }           
            }else if(card_type == CardType.DefuseBoom){
                if(player.pick_boom){
                    player.DefuseBoom();
                    player.card_type_list.pop(); //炸弹肯定是最后一张手牌
                    GameController.getInstance().OpenPutBoomView(this.card_heap_list, (put_index) => {
                        this.card_heap_list.splice(put_index, 0, CardType.Boom);
                        console.log(this.card_heap_list);
                        this.game_sub_state = GameSubState.NextTurn;
                    });
                    this.game_sub_state = GameSubState.PlayPutBoom;
                    return;
                }
                this.ChangeToGamePlayUpdateTime(player, true);
            }
        }

        this.target_player_item = null;
        this.send_card = null;
    }
    
}